/*
 * GPLv3 License
 *
 * Copyright (c) 2023-2025 4ra1n (Jar Analyzer Team)
 *
 * This project is distributed under the GPLv3 license.
 *
 * https://github.com/jar-analyzer/jar-analyzer/blob/master/LICENSE
 */

package me.n1ar4.jar.analyzer.gui.vul;

import com.intellij.uiDesigner.core.GridConstraints;
import me.n1ar4.jar.analyzer.engine.CoreHelper;
import me.n1ar4.jar.analyzer.engine.SearchCondition;
import me.n1ar4.jar.analyzer.gui.MainForm;
import me.n1ar4.jar.analyzer.utils.IOUtils;
import me.n1ar4.jar.analyzer.utils.YamlUtil;
import me.n1ar4.log.LogManager;
import me.n1ar4.log.Logger;

import javax.swing.*;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class VulnerabilityBuilder {
    private static final Logger logger = LogManager.getLogger();

    private static JPanel javaVulSearchPanel;

    private static Rule rule = null;

    private static void createUI() {
        Iterator<Map.Entry<String, List<SearchCondition>>> iter = rule.getVulnerabilities().entrySet().iterator();
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 3; j++) {
                if (!iter.hasNext()) {
                    break;
                }
                Map.Entry<String, List<SearchCondition>> entry = iter.next();
                String vName = entry.getKey();
                JButton vButton = new JButton();
                vButton.setText(vName);
                javaVulSearchPanel.add(vButton,
                        new GridConstraints((i + 1), j, 1, 1,
                                GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL,
                                GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                                GridConstraints.SIZEPOLICY_FIXED,
                                null,
                                null,
                                null,
                                0,
                                false));
                vButton.addActionListener(e -> {
                    if (MainForm.getEngine() == null || !MainForm.getEngine().isEnabled()) {
                        return;
                    }
                    new Thread(() -> CoreHelper.refreshCallSearchList(entry.getValue())).start();
                });
                logger.info("build {} vulnerability gui", entry.getKey());
            }
        }
    }

    private static void loadVulnerabilities() {
        Path vPath = Paths.get("vulnerability.yaml");
        InputStream is = null;
        if (!Files.exists(vPath)) {
            logger.warn("vulnerability.yaml not found");
            logger.info("use builtin vulnerability.yaml rule");
            is = VulnerabilityBuilder.class.getClassLoader().getResourceAsStream("vulnerability.yaml");
            if (is == null) {
                logger.error("builtin vulnerability.yaml not found");
                return;
            }
        } else {
            logger.info("use vulnerability.yaml rule");
            try {
                is = Files.newInputStream(vPath.toFile().toPath());
            } catch (Exception ignored) {
            }
        }
        try {
            byte[] yamlData = IOUtils.readAllBytes(is);
            rule = YamlUtil.loadAs(yamlData);
        } catch (Exception ex) {
            logger.error("load vulnerability.yaml failed : {}", ex.getMessage());
        }
    }

    public static void build(MainForm main) {
        javaVulSearchPanel = main.getJavaVulSearchPanel();
        loadVulnerabilities();
        createUI();
    }
}
